// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   SettableListenableFuture.java

package org.springframework.util.concurrent;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import org.springframework.util.Assert;

// Referenced classes of package org.springframework.util.concurrent:
//			ListenableFutureTask, ListenableFuture, ListenableFutureCallback, SuccessCallback, 
//			FailureCallback

public class SettableListenableFuture
	implements ListenableFuture
{
	private static class SettableTask
		implements Callable
	{

		private static final String NO_VALUE = (new StringBuilder()).append(org/springframework/util/concurrent/SettableListenableFuture.getName()).append(".NO_VALUE").toString();
		private final AtomicReference value;
		private volatile boolean cancelled;

		public boolean setValue(Object value)
		{
			if (cancelled)
				return false;
			else
				return this.value.compareAndSet(NO_VALUE, value);
		}

		public boolean setException(Throwable exception)
		{
			if (cancelled)
				return false;
			else
				return value.compareAndSet(NO_VALUE, exception);
		}

		public void setCancelled()
		{
			cancelled = true;
		}

		public Object call()
			throws Exception
		{
			if (value.get() instanceof Exception)
				throw (Exception)value.get();
			else
				return value.get();
		}


		private SettableTask()
		{
			value = new AtomicReference(NO_VALUE);
			cancelled = false;
		}

	}


	private final SettableTask settableTask = new SettableTask();
	private final ListenableFutureTask listenableFuture;

	public SettableListenableFuture()
	{
		listenableFuture = new ListenableFutureTask(settableTask);
	}

	public boolean set(Object value)
	{
		boolean success = settableTask.setValue(value);
		if (success)
			listenableFuture.run();
		return success;
	}

	public boolean setException(Throwable exception)
	{
		Assert.notNull(exception, "'exception' must not be null");
		boolean success = settableTask.setException(exception);
		if (success)
			listenableFuture.run();
		return success;
	}

	public void addCallback(ListenableFutureCallback callback)
	{
		listenableFuture.addCallback(callback);
	}

	public void addCallback(SuccessCallback successCallback, FailureCallback failureCallback)
	{
		listenableFuture.addCallback(successCallback, failureCallback);
	}

	public boolean cancel(boolean mayInterruptIfRunning)
	{
		settableTask.setCancelled();
		boolean cancelled = listenableFuture.cancel(mayInterruptIfRunning);
		if (cancelled && mayInterruptIfRunning)
			interruptTask();
		return cancelled;
	}

	public boolean isCancelled()
	{
		return listenableFuture.isCancelled();
	}

	public boolean isDone()
	{
		return listenableFuture.isDone();
	}

	public Object get()
		throws InterruptedException, ExecutionException
	{
		return listenableFuture.get();
	}

	public Object get(long timeout, TimeUnit unit)
		throws InterruptedException, ExecutionException, TimeoutException
	{
		return listenableFuture.get(timeout, unit);
	}

	protected void interruptTask()
	{
	}
}
